package com.dcy.inventory.center.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dcy.inventory.api.api.InventoryApi;
import com.dcy.inventory.api.dto.InventoryDTO;
import com.dcy.inventory.api.model.Inventory;
import com.dcy.inventory.center.mapper.InventoryMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.hmily.annotation.HmilyTCC;
import org.dromara.hmily.common.exception.HmilyRuntimeException;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author dcy
 * @since 2021-11-16
 */
@Slf4j
@DubboService(version = "1.0.0", timeout = 3000, retries = 0, interfaceClass = InventoryApi.class)
public class InventoryService extends ServiceImpl<InventoryMapper, Inventory> implements InventoryApi {

    private static AtomicInteger confirmCount = new AtomicInteger(0);

    @Override
    @HmilyTCC(confirmMethod = "confirmMethod", cancelMethod = "cancelMethod")
    public Boolean decrease(InventoryDTO inventoryDTO) {
        log.info("decrease {}", inventoryDTO);
        return baseMapper.decrease(inventoryDTO) > 0;
    }

    @Override
    @HmilyTCC(confirmMethod = "confirmMethod", cancelMethod = "cancelMethod")
    public String mockWithTryException(InventoryDTO inventoryDTO) {
        //这里是模拟异常所以就直接抛出异常了
        throw new HmilyRuntimeException("库存扣减异常！");
    }

    @Override
    @HmilyTCC(confirmMethod = "confirmMethod", cancelMethod = "cancelMethod")
    @Transactional(rollbackFor = Exception.class)
    public Boolean mockWithTryTimeout(InventoryDTO inventoryDTO) {
        try {
            //模拟延迟 当前线程暂停10秒
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        final int decrease = baseMapper.decrease(inventoryDTO);
        if (decrease != 1) {
            throw new HmilyRuntimeException("库存不足");
        }
        return true;
    }

    /**
     * Confirm method boolean.
     *
     * @param inventoryDTO the inventory dto
     * @return the boolean
     */
    public Boolean confirmMethod(InventoryDTO inventoryDTO) {
        log.info("==========调用扣减库存confirm方法===========");
        baseMapper.confirm(inventoryDTO);
        final int i = confirmCount.incrementAndGet();
        log.info("调用了inventory confirm " + i + " 次");
        return true;
    }

    /**
     * Cancel method boolean.
     *
     * @param inventoryDTO the inventory dto
     * @return the boolean
     */
    public Boolean cancelMethod(InventoryDTO inventoryDTO) {
        log.info("==========调用扣减库存取消方法===========");
        baseMapper.cancel(inventoryDTO);
        return true;
    }
}
